{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# Get Started\n",
    "## Install python package\n",
    "You can install `python-okx` from PyPi server."
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "! pip install python-okx --upgrade"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sign up as an OKX user\n",
    "Please refer to [Create account](https://www.okx.com/account/register)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create API Key\n",
    "Please refer to [Create API Key](https://www.okx.com/account/my-api)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Import API modules\n",
    "The following modules are available\n",
    "- Trade\n",
    "- BlockTrading\n",
    "- Funding\n",
    "- Account\n",
    "- Convert\n",
    "- Earning\n",
    "- SubAccount\n",
    "- MarketData\n",
    "- PublicData\n",
    "- TradingData\n",
    "- Status\n",
    "- NDBroker\n",
    "- FDBroker"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "is_executing": true
    }
   },
   "outputs": [],
   "source": [
    "import okx.Trade as Trade"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fill in your API key details"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "api_key = \"xxxxx\"\n",
    "secret_key = \"xxxxx\"\n",
    "passphrase = \"xxxxxx\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get available funds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "is_executing": true
    }
   },
   "outputs": [],
   "source": [
    "import okx.Funding as Funding\n",
    "\n",
    "flag = \"1\"  # live trading: 0, demo trading: 1\n",
    "\n",
    "fundingAPI = Funding.FundingAPI(api_key, secret_key, passphrase, False, flag)\n",
    "\n",
    "result = fundingAPI.get_currencies()\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get market data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "is_executing": true
    }
   },
   "outputs": [],
   "source": [
    "import okx.MarketData as MarketData\n",
    "\n",
    "flag = \"1\"  # live trading: 0, demo trading: 1\n",
    "\n",
    "marketDataAPI = MarketData.MarketAPI(flag=flag)\n",
    "\n",
    "result = marketDataAPI.get_tickers(instType=\"SPOT\")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Handle errors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You will the error code `51000` when. you run the following code. More details about the error code can be found in `msg`.\n",
    "Please refer to  [error code](https://www.okx.com/docs-v5/en/#error-code) for addtional information."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "pycharm": {
     "is_executing": true
    }
   },
   "outputs": [],
   "source": [
    "import okx.MarketData as MarketData\n",
    "\n",
    "flag = \"1\"  # live trading: 0, demo trading: 1\n",
    "\n",
    "marketDataAPI = MarketData.MarketAPI(flag=flag)\n",
    "\n",
    "result = marketDataAPI.get_tickers( instType=\"SPOT\")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Prepare for trading\n",
    "- Make sure you understand the basic trading rules. Please refer to [Basic Trading Rules](https://www.okx.com/support/hc/en-us/sections/360011507312)\n",
    "- Make sure you have enough funds in your trading account。Please refer to  [Get balance](https://www.okx.com/docs-v5/en/#rest-api-account-get-balance)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get account balance. Please refer to  [Get balance](https://www.okx.com/docs-v5/en/#rest-api-account-get-balance)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import okx.Account as Account\n",
    "flag = \"1\"  # live trading: 0, demo trading: 1\n",
    "\n",
    "accountAPI = Account.AccountAPI(api_key, secret_key, passphrase, False, flag)\n",
    "\n",
    "result = accountAPI.get_account_balance()\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get available trading pairs from [Get instruments](https://www.okx.com/docs-v5/en/#rest-api-public-data-get-instruments)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import okx.PublicData as PublicData\n",
    "\n",
    "flag = \"1\"  # live trading: 0, demo trading: 1\n",
    "\n",
    "PublicDataAPI = PublicData.PublicAPI(flag=flag)\n",
    "\n",
    "result = PublicDataAPI.get_instruments(\n",
    "   instType=\"SPOT\"\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Make sure you have enough funds to trade a certain pair. Please refer to [Get maximum tradable amount](https://www.okx.com/docs-v5/en/#rest-api-account-get-maximum-available-tradable-amount)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import okx.Account as Account\n",
    "\n",
    "flag = \"1\"  # live trading: 0, demo trading: 1\n",
    "\n",
    "accountAPI = Account.AccountAPI(api_key, secret_key, passphrase, False, flag)\n",
    "\n",
    "result = accountAPI.get_max_avail_size(\n",
    "    instId=\"BTC-USDT\",\n",
    "    tdMode=\"cash\"\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import okx.Account as Account\n",
    "\n",
    "flag = \"1\"  # live trading: 0, demo trading: 1\n",
    "\n",
    "accountAPI = Account.AccountAPI(api_key, secret_key, passphrase, False, flag)\n",
    "\n",
    "result = accountAPI.get_max_avail_size(\n",
    "    instId=\"BTC-USDT\",\n",
    "    tdMode=\"cash\"\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## In unified account, you can trade Spot under simple, single currency, multi currency and portfolio margin account mode. Please refer to [Introduction on Unified Account](https://www.okx.com/support/hc/en-us/articles/360054690791-1-统一交易账户介绍)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get the current account configuration from the `acctLv` parameter in [Get account configuration](https://www.okx.com/docs-v5/en/#rest-api-account-get-account-configuration)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import okx.Account as Account\n",
    "\n",
    "flag = \"1\"  # live trading: 0, demo trading: 1\n",
    "\n",
    "accountAPI = Account.AccountAPI(api_key, secret_key, passphrase, False, flag)\n",
    "result = accountAPI.get_account_config()\n",
    "print(result)\n",
    "\n",
    "if result['code'] == \"0\":\n",
    "    acctLv = result[\"data\"][0][\"acctLv\"]\n",
    "    if acctLv == \"1\":\n",
    "        print(\"Simple mode\")\n",
    "    elif acctLv == \"2\":\n",
    "        print(\"Single-currency margin mode\")\n",
    "    elif acctLv == \"3\":\n",
    "        print(\"Multi-currency margin mode\")\n",
    "    elif acctLv == \"4\":\n",
    "        print(\"Portfolio margin mode\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Start Spot Trading"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Spot trading under simple/single-currency margin mode"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import okx.Trade as Trade\n",
    "\n",
    "flag = \"1\"  # live trading: 0, demo trading: 1\n",
    "\n",
    "tradeAPI = Trade.TradeAPI(api_key, secret_key, passphrase, False, flag)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### place a limit order"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# limit order\n",
    "result = tradeAPI.place_order(\n",
    "    instId=\"BTC-USDT\",\n",
    "    tdMode=\"cash\",\n",
    "    side=\"buy\",\n",
    "    ordType=\"limit\",\n",
    "    px=\"19000\",\n",
    "    sz=\"0.01\"\n",
    ")\n",
    "print(result)\n",
    "\n",
    "if result[\"code\"] == \"0\":\n",
    "    print(\"Successful order request，order_id = \",result[\"data\"][0][\"ordId\"])\n",
    "else:\n",
    "    print(\"Unsuccessful order request，error_code = \",result[\"data\"][0][\"sCode\"], \", Error_message = \", result[\"data\"][0][\"sMsg\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### place a market order"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#  market order\n",
    "result = tradeAPI.place_order(\n",
    "    instId=\"BTC-USDT\",\n",
    "    tdMode=\"cash\",\n",
    "    side=\"buy\",\n",
    "    ordType=\"market\",\n",
    "    sz=\"100\",\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### place an order with tgtCcy=quote_ccy (only applicable to spot)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#  market order\n",
    "result = tradeAPI.place_order(\n",
    "    instId=\"BTC-USDT\",\n",
    "    tdMode=\"cash\",\n",
    "    side=\"buy\",\n",
    "    ordType=\"market\",\n",
    "    sz=\"100\",\n",
    "    tgtCcy=\"quote_ccy\" # this determines the unit of the sz parameter. base_ccy is the default value\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### place an order with your own clOrdId"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#  market order\n",
    "result = tradeAPI.place_order(\n",
    "    instId=\"BTC-USDT\",\n",
    "    tdMode=\"cash\",\n",
    "    side=\"buy\",\n",
    "    ordType=\"market\",\n",
    "    sz=\"100\",\n",
    "    clOrdId=\"003\" # you can define your own client defined order ID\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Spot trading under multi-currency/porfolio margin mode"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# cross-margin spot trading\n",
    "result = tradeAPI.place_order(\n",
    "    instId=\"BTC-USDT\",\n",
    "    tdMode=\"cross\",\n",
    "    side=\"buy\",\n",
    "    ordType=\"limit\",\n",
    "    px=\"1000\",\n",
    "    sz=\"0.01\"\n",
    ")\n",
    "print(result)\n",
    "\n",
    "if result[\"code\"] == \"0\":\n",
    "    print(\"Successful order request，order_id = \",result[\"data\"][0][\"ordId\"])\n",
    "else:\n",
    "    print(\"Unsuccessful order request，error_code = \",result[\"data\"][0][\"sCode\"], \", Error_message = \", result[\"data\"][0][\"sMsg\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### For additional information on the place order endpoint，please refer to [Place order](https://www.okx.com/docs-v5/en/#rest-api-trade-place-order)\n",
    "\n",
    "### To place orders in a batch, please refer to [Get account configuration](https://www.okx.com/docs-v5/en/#rest-api-trade-place-multiple-orders)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "place_orders = [\n",
    "    {\"instId\":\"BTC-USDT\", \"tdMode\":\"cash\", \"side\":\"buy\", \"ordType\" : \"limit\",\"px\":\"1000\",\"sz\":\"0.01\"},\n",
    "    {\"instId\": \"BTC-USDT\", \"tdMode\": \"cash\", \"side\": \"buy\", \"ordType\": \"limit\", \"px\": \"1000\", \"sz\": \"0.02\"}\n",
    "]\n",
    "\n",
    "result = tradeAPI.place_multiple_orders(place_orders)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### To amend pending orders，please refer to [Amend order](https://www.okx.com/docs-v5/en/#rest-api-trade-amend-order)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = tradeAPI.amend_order(\n",
    "    instId=\"BTC-USDT\",\n",
    "    ordId=\"489103565508685824\",\n",
    "    newSz=\"0.012\"\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### To amend orders in a batch, please refer to [Amend multiple orders](https://www.okx.com/docs-v5/en/#rest-api-trade-amend-multiple-orders)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "amend_orders = [\n",
    "    {\"instId\": \"BTC-USDT\", \"ordId\": \"489106394289909760\",\"newSz\":\"0.001\"},\n",
    "    {\"instId\": \"BTC-USDT\", \"ordId\": \"489106394289909761\",\"newSz\":\"0.001\"},\n",
    "]\n",
    "\n",
    "result = tradeAPI.amend_multiple_orders(amend_orders)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### To cancel pending orders，please refer to [Cancel order](https://www.okx.com/docs-v5/en/#rest-api-trade-cancel-order)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = tradeAPI.cancel_order(instId=\"BTC-USDT\", ordId = \"489093931993509888\")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### To cancel orders in a batch，please refer to [Cancel multiple orders](https://www.okx.com/docs-v5/zh/#rest-api-trade-cancel-multiple-orders)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cancel_orders = [\n",
    "    {\"instId\": \"BTC-USDT\", \"ordId\": \"489102222534488064\"},\n",
    "    {\"instId\": \"BTC-USDT\", \"ordId\": \"489102222534488065\"},\n",
    "]\n",
    "\n",
    "result = tradeAPI.cancel_multiple_orders(cancel_orders)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get details of a certain order, please refer to [Get order details](https://www.okx.com/docs-v5/en/#rest-api-trade-get-order-details)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = tradeAPI.get_order(instId=\"BTC-USDT\", clOrdId=\"002\")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = tradeAPI.get_order(instId=\"BTC-USDT\", ordId=\"497819823594909696\")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## To get the list of open orders，please refer to [Get order List](https://www.okx.com/docs-v5/en/#rest-api-trade-get-order-list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = tradeAPI.get_order_list()\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### To get past orders，please refer to [Get order history (last 7 days）](https://www.okx.com/docs-v5/en/#rest-api-trade-get-order-history-last-7-days) and [Get order history (last 3 months)](https://www.okx.com/docs-v5/en/#rest-api-trade-get-order-history-last-3-months)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = tradeAPI.get_orders_history(\n",
    "    instType=\"SPOT\"\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = tradeAPI.get_orders_history_archive(\n",
    "    instType=\"SPOT\"\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### To get past trades，please refer to [Get transaction details (last 3 days）](https://www.okx.com/docs-v5/en/#rest-api-trade-get-transaction-details-last-3-days) and [Get transaction details (last 3 months) ](https://www.okx.com/docs-v5/en/#rest-api-trade-get-transaction-details-last-3-months)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = tradeAPI.get_fills(\n",
    "    instType=\"SPOT\"\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = tradeAPI.get_fills_history(\n",
    "    instType=\"SPOT\"\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### If you wish to place orders when the price reaches a certain level, you can place an algo order"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = tradeAPI.place_algo_order(\n",
    "    instId=\"BTC-USDT\",\n",
    "    tdMode=\"cash\",\n",
    "    side=\"buy\",             # buy\n",
    "    ordType=\"trigger\",      # order type\n",
    "    sz=\"100\",               # order amount: 100USDT\n",
    "    triggerPx=\"10000\",      # trigger price\n",
    "    orderPx=\"-1\",           # order price. When orderPx=-1, the order will be placed as an market order\n",
    "    triggerPxType=\"last\"    # trigger price type。last：last trade price\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## You can also use Stop Loss or Take Profit order to sell the currencies in your account"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = tradeAPI.place_algo_order(\n",
    "    instId=\"BTC-USDT\",\n",
    "    tdMode=\"cash\",\n",
    "    side=\"sell\",                # sell\n",
    "    ordType=\"conditional\",      # one-way take profit or stop loss\n",
    "    sz=\"0.01\",               # order amount: 0.01BTC\n",
    "    tpTriggerPx=\"30000\",      # take profit trigger price\n",
    "    tpOrdPx=\"-1\",           # taker profit order price。When it is set to -1，the order will be placed as an market order\n",
    "    tpTriggerPxType=\"last\"    # take profit trigger price type。last：last trade price\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### For additional information, please refer to  [Place algo order](https://www.okx.com/docs-v5/en/#rest-api-trade-place-algo-order)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Cancel pending algo orders (not including Iceberg order, TWAP order, Trailing Stop order)，please refer to [Cancel algo order](https://www.okx.com/docs-v5/en/#rest-api-trade-cancel-algo-order)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "algo_orders = [\n",
    "    {\"instId\": \"BTC-USDT\", \"algoId\": \"495001187587043328\"},\n",
    "]\n",
    "\n",
    "result = tradeAPI.cancel_algo_order(algo_orders)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### To get list of currently pending algo orders，please refer to [Get algo order list](https://www.okx.com/docs-v5/en/#rest-api-trade-get-algo-order-list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = tradeAPI.order_algos_list(\n",
    "    ordType=\"trigger\"     # order type\n",
    ")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### To get the past algo orders (last three months)，please refer to [Get algo order history](https://www.okx.com/docs-v5/en/#rest-api-trade-get-algo-order-history)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = tradeAPI.order_algos_history(\n",
    "    ordType=\"conditional\",     # order type\n",
    "    state=\"canceled\"           # state of the orders\n",
    ")\n",
    "print(result)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  },
  "vscode": {
   "interpreter": {
    "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
